package com.smart.community.property.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.smart.community.commons.exception.BusinessException;
import com.smart.community.commons.result.ResultCode;
import com.smart.community.property.dto.FeeDuplicateCheckResult;
import com.smart.community.property.entity.PropertyFee;
import com.smart.community.property.entity.SanitationFee;
import com.smart.community.property.mapper.PropertyFeeMapper;
import com.smart.community.property.mapper.SanitationFeeMapper;
import com.smart.community.property.service.FeeDuplicateCheckService;
import com.smart.community.property.utils.MonthRangeUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * 费用重复检查服务实现类
 * 
 * @author Wu.Liang
 * @since 2025-01-30
 * @version 1.0.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class FeeDuplicateCheckServiceImpl implements FeeDuplicateCheckService {

    private final PropertyFeeMapper propertyFeeMapper;
    private final SanitationFeeMapper sanitationFeeMapper;

    @Override
    public FeeDuplicateCheckResult checkPropertyFeeDuplicate(Long communityId, String billingPeriod, Integer feeType) {
        log.info("检查物业费重复，社区ID: {}, 计费周期: {}, 费用类型: {}", communityId, billingPeriod, feeType);
        
        try {
            if (communityId == null || !StringUtils.hasText(billingPeriod) || feeType == null) {
                return FeeDuplicateCheckResult.error("参数不完整");
            }
            
            if (!MonthRangeUtils.isValidBillingPeriod(billingPeriod)) {
                return FeeDuplicateCheckResult.error("计费周期格式不正确");
            }
            
            LambdaQueryWrapper<PropertyFee> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(PropertyFee::getCommunityId, communityId)
                   .eq(PropertyFee::getBillingPeriod, billingPeriod)
                   .eq(PropertyFee::getFeeType, feeType)
                   .eq(PropertyFee::getDeleted, 0);
            
            long count = propertyFeeMapper.selectCount(wrapper);
            if (count > 0) {
                log.warn("物业费重复，社区ID: {}, 计费周期: {}, 重复数量: {}", communityId, billingPeriod, count);
                return FeeDuplicateCheckResult.hasDuplicate("community", (int) count, null, null);
            }
            
            return FeeDuplicateCheckResult.noDuplicate();
            
        } catch (Exception e) {
            log.error("检查物业费重复失败，社区ID: {}, 计费周期: {}", communityId, billingPeriod, e);
            return FeeDuplicateCheckResult.error("检查失败：" + e.getMessage());
        }
    }

    @Override
    public FeeDuplicateCheckResult checkSanitationFeeDuplicate(Long communityId, String billingPeriod) {
        log.info("检查卫生费重复，社区ID: {}, 计费周期: {}", communityId, billingPeriod);
        
        try {
            if (communityId == null || !StringUtils.hasText(billingPeriod)) {
                return FeeDuplicateCheckResult.error("参数不完整");
            }
            
            if (!MonthRangeUtils.isValidBillingPeriod(billingPeriod)) {
                return FeeDuplicateCheckResult.error("计费周期格式不正确");
            }
            
            LambdaQueryWrapper<SanitationFee> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SanitationFee::getCommunityId, communityId)
                   .eq(SanitationFee::getBillingPeriod, billingPeriod)
                   .eq(SanitationFee::getDeleted, 0);
            
            long count = sanitationFeeMapper.selectCount(wrapper);
            if (count > 0) {
                log.warn("卫生费重复，社区ID: {}, 计费周期: {}, 重复数量: {}", communityId, billingPeriod, count);
                return FeeDuplicateCheckResult.hasDuplicate("community", (int) count, null, null);
            }
            
            return FeeDuplicateCheckResult.noDuplicate();
            
        } catch (Exception e) {
            log.error("检查卫生费重复失败，社区ID: {}, 计费周期: {}", communityId, billingPeriod, e);
            return FeeDuplicateCheckResult.error("检查失败：" + e.getMessage());
        }
    }

    @Override
    public FeeDuplicateCheckResult checkHouseholdFeeDuplicate(Long householdId, String billingPeriod, Integer feeType) {
        log.info("检查房户费用重复，房户ID: {}, 计费周期: {}, 费用类型: {}", householdId, billingPeriod, feeType);
        
        try {
            if (householdId == null || !StringUtils.hasText(billingPeriod) || feeType == null) {
                return FeeDuplicateCheckResult.error("参数不完整");
            }
            
            if (!MonthRangeUtils.isValidBillingPeriod(billingPeriod)) {
                return FeeDuplicateCheckResult.error("计费周期格式不正确");
            }
            
            if (feeType == 1) {
                // 物业费
                LambdaQueryWrapper<PropertyFee> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(PropertyFee::getHouseholdId, householdId)
                       .eq(PropertyFee::getFeeType, feeType)
                       .eq(PropertyFee::getDeleted, 0);
                
                long count = propertyFeeMapper.selectCount(wrapper);
                if (count > 0) {
                    return FeeDuplicateCheckResult.hasDuplicate("household", (int) count, null, null);
                }
            } else if (feeType == 5) {
                // 卫生费
                LambdaQueryWrapper<SanitationFee> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(SanitationFee::getHouseholdId, householdId)
                       .eq(SanitationFee::getDeleted, 0);
                
                long count = sanitationFeeMapper.selectCount(wrapper);
                if (count > 0) {
                    return FeeDuplicateCheckResult.hasDuplicate("household", (int) count, null, null);
                }
            }
            
            return FeeDuplicateCheckResult.noDuplicate();
            
        } catch (Exception e) {
            log.error("检查房户费用重复失败，房户ID: {}, 计费周期: {}", householdId, billingPeriod, e);
            return FeeDuplicateCheckResult.error("检查失败：" + e.getMessage());
        }
    }

    @Override
    public void validatePropertyFeeGeneration(Long communityId, String billingPeriod, Integer feeType) {
        FeeDuplicateCheckResult result = checkPropertyFeeDuplicate(communityId, billingPeriod, feeType);
        
        if (result.isHasDuplicate()) {
            String errorMessage = "该社区已存在计费周期为 " + billingPeriod + " 的物业费记录";
            throw new BusinessException(ResultCode.OPERATION_FAILED.getCode(), errorMessage);
        }
    }

    @Override
    public void validateSanitationFeeGeneration(Long communityId, String billingPeriod) {
        FeeDuplicateCheckResult result = checkSanitationFeeDuplicate(communityId, billingPeriod);
        
        if (result.isHasDuplicate()) {
            String errorMessage = "该社区已存在计费周期为 " + billingPeriod + " 的卫生费记录";
            throw new BusinessException(ResultCode.OPERATION_FAILED.getCode(), errorMessage);
        }
    }
}
